In [1]:
import os
import math
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
import plotly.graph_objects as go
import pickle
In [2]:
%%time

if os.path.exists('contagem_geral.pickle'):
    print('O arquivo de contagem geral existe, carregando...')
    with open('contagem_geral.pickle', 'rb') as file:
        contagem_geral = pickle.load(file)
    print('Importação concluída!\n')
else:
    print('Erro! Antes de executar a análise, execute o Notebook 01 de Carga.')
O arquivo de contagem geral existe, carregando...
Importação concluída!

CPU times: user 1.47 s, sys: 562 ms, total: 2.04 s
Wall time: 2.04 s
In [3]:
contagem_geral.head()
Out[3]:
senha ocorrencias caracteres caracteres_unicos ocorrencias_percentuais
0 123456 20963035 6 6 0.050208
1 12345 7030768 5 5 0.016839
2 12345678 3521408 8 8 0.008434
3 111111 2906365 6 1 0.006961
4 1234567 2363539 7 7 0.005661
In [4]:
contagem_geral.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 24140087 entries, 0 to 24140086
Data columns (total 5 columns):
 #   Column                   Dtype  
---  ------                   -----  
 0   senha                    object 
 1   ocorrencias              int64  
 2   caracteres               int64  
 3   caracteres_unicos        int64  
 4   ocorrencias_percentuais  float64
dtypes: float64(1), int64(3), object(1)
memory usage: 920.9+ MB
In [5]:
contagem_geral.describe(include='number')
Out[5]:
ocorrencias caracteres caracteres_unicos ocorrencias_percentuais
count 2.414009e+07 2.414009e+07 2.414009e+07 2.414009e+07
mean 1.729590e+01 7.552672e+00 5.390836e+00 4.142487e-08
std 4.729153e+03 5.999113e-01 9.879169e-01 1.132665e-05
min 1.000000e+00 4.000000e+00 1.000000e+00 2.395069e-09
25% 1.000000e+00 7.000000e+00 5.000000e+00 2.395069e-09
50% 2.000000e+00 8.000000e+00 5.000000e+00 4.790138e-09
75% 4.000000e+00 8.000000e+00 6.000000e+00 9.580277e-09
max 2.096304e+07 8.000000e+00 8.000000e+00 5.020792e-02
In [6]:
amostra = contagem_geral.sample(100_000)

Vamos entender a distribuição das senhasm no sentido de saber se há muitas senhas pouco usadas e poucas senhas muito usadas.

Se isso se confirmar, podemos, por exemplo, estudar apenas as senhas que apareçam N vezes ou mais.

In [7]:
fig = px.box(amostra, y='ocorrencias', hover_data='senha', height=600, width=600)
fig.show()

A grande maioria das senhas (mais de 75% de toda a base) aparece menos de 10 vezes (ao menos na amostra).

Utilizaremos uma quantidade de senhas que permita capturar as entradas relevantes, porém ainda com uma quantidade significativa, acima de 100 mil de entradas.

In [8]:
contagem_selecionada = contagem_geral.query('ocorrencias > 1000')
print(contagem_selecionada.info())
contagem_selecionada.describe()
<class 'pandas.core.frame.DataFrame'>
Index: 50296 entries, 0 to 50295
Data columns (total 5 columns):
 #   Column                   Non-Null Count  Dtype  
---  ------                   --------------  -----  
 0   senha                    50296 non-null  object 
 1   ocorrencias              50296 non-null  int64  
 2   caracteres               50296 non-null  int64  
 3   caracteres_unicos        50296 non-null  int64  
 4   ocorrencias_percentuais  50296 non-null  float64
dtypes: float64(1), int64(3), object(1)
memory usage: 2.3+ MB
None
Out[8]:
ocorrencias caracteres caracteres_unicos ocorrencias_percentuais
count 5.029600e+04 50296.000000 50296.000000 50296.000000
mean 4.269271e+03 6.740317 4.667667 0.000010
std 1.035166e+05 1.155383 1.187251 0.000248
min 1.001000e+03 4.000000 1.000000 0.000002
25% 1.355000e+03 6.000000 4.000000 0.000003
50% 2.010000e+03 6.000000 5.000000 0.000005
75% 3.576000e+03 8.000000 5.000000 0.000009
max 2.096304e+07 8.000000 8.000000 0.050208
In [9]:
fig = px.box(contagem_selecionada, y='ocorrencias', hover_data='senha', height=600, width=600)
fig.show()
In [10]:
contagem_selecionada.head(100)
Out[10]:
senha ocorrencias caracteres caracteres_unicos ocorrencias_percentuais
0 123456 20963035 6 6 0.050208
1 12345 7030768 5 5 0.016839
2 12345678 3521408 8 8 0.008434
3 111111 2906365 6 1 0.006961
4 1234567 2363539 7 7 0.005661
... ... ... ... ... ...
95 159159 82353 6 3 0.000197
96 123457 81928 6 6 0.000196
97 565656 81926 6 2 0.000196
98 123098 80919 6 6 0.000194
99 123987 80804 6 6 0.000194

100 rows × 5 columns

In [11]:
fig = px.violin(contagem_selecionada, y='caracteres_unicos', x= 'caracteres', box=False, height=600, width=1200)
fig.show()
In [12]:
senhas_4_digitos = contagem_selecionada.query('caracteres == 4')
senhas_5_digitos = contagem_selecionada.query('caracteres == 5')
senhas_6_digitos = contagem_selecionada.query('caracteres == 6')
senhas_7_digitos = contagem_selecionada.query('caracteres == 7')
senhas_8_digitos = contagem_selecionada.query('caracteres == 8')
In [13]:
rotulos = ['senhas_4_digitos', 'senhas_5_digitos', 'senhas_6_digitos', 'senhas_7_digitos', 'senhas_8_digitos']
tamanhos = [len(senhas_4_digitos), len(senhas_5_digitos), len(senhas_6_digitos), len(senhas_7_digitos), len(senhas_8_digitos)]

fig = px.bar(y=tamanhos, x=rotulos, height=600, width=1200)
fig.show()

Senhas de 4 Dígitos¶

Vamos analisar, para cada uma das 4 posições, qual a frequência observada dos 10 possíveis dígitos.

Para isso, vamos considerar os dígitos da esquerda para a direita.

Por exemplo, no caso de 1234:

  • Primeiro: 1
  • Segundo: 2
  • Terceiro: 3
  • Quarto: 4
In [14]:
contador = 0
print('-' * 70, '\n\n')
for pos in ['primeiro', 'segundo', 'terceiro', 'quarto']:
    
    digito = []
    digito_contagem = {}
    
    for i in senhas_4_digitos['senha'].values:
        digito.append(i[contador])
    
    for i in set(digito):
        digito_contagem[i] = digito.count(i)

    digito_contagem = dict(sorted(digito_contagem.items()))
    
    print(f'Frequência dos dígitos no {pos} dígito:\n', digito_contagem)
    
    fig = px.bar(x=digito_contagem.keys(), y=digito_contagem.values(), height=600, width=1200)
    fig.show()

    print('-' * 70, '\n\n')
    contador = contador + 1
---------------------------------------------------------------------- 


Frequência dos dígitos no primeiro dígito:
 {'0': 310, '1': 799, '2': 511, '3': 172, '4': 110, '5': 110, '6': 56, '7': 85, '8': 60, '9': 52}
---------------------------------------------------------------------- 


Frequência dos dígitos no segundo dígito:
 {'0': 201, '1': 283, '2': 279, '3': 255, '4': 214, '5': 283, '6': 184, '7': 173, '8': 198, '9': 195}
---------------------------------------------------------------------- 


Frequência dos dígitos no terceiro dígito:
 {'0': 369, '1': 358, '2': 347, '3': 186, '4': 139, '5': 174, '6': 157, '7': 166, '8': 206, '9': 163}
---------------------------------------------------------------------- 


Frequência dos dígitos no quarto dígito:
 {'0': 247, '1': 278, '2': 229, '3': 216, '4': 197, '5': 239, '6': 207, '7': 200, '8': 223, '9': 229}
---------------------------------------------------------------------- 


Senhas de 5 Dígitos¶

In [15]:
contador = 0
print('-' * 70, '\n\n')
for pos in ['primeiro', 'segundo', 'terceiro', 'quarto', 'quinto']:
    
    digito = []
    digito_contagem = {}
    
    for i in senhas_5_digitos['senha'].values:
        digito.append(i[contador])
    
    for i in set(digito):
        digito_contagem[i] = digito.count(i)

    digito_contagem = dict(sorted(digito_contagem.items()))
    
    print(f'Frequência dos dígitos no {pos} dígito:\n', digito_contagem)
    
    fig = px.bar(x=digito_contagem.keys(), y=digito_contagem.values(), height=600, width=1200)
    fig.show()

    print('-' * 70, '\n\n')
    contador = contador + 1
---------------------------------------------------------------------- 


Frequência dos dígitos no primeiro dígito:
 {'0': 120, '1': 557, '2': 354, '3': 68, '4': 33, '5': 29, '6': 28, '7': 41, '8': 24, '9': 33}
---------------------------------------------------------------------- 


Frequência dos dígitos no segundo dígito:
 {'0': 176, '1': 179, '2': 206, '3': 123, '4': 93, '5': 123, '6': 78, '7': 77, '8': 86, '9': 146}
---------------------------------------------------------------------- 


Frequência dos dígitos no terceiro dígito:
 {'0': 512, '1': 361, '2': 61, '3': 76, '4': 29, '5': 35, '6': 41, '7': 51, '8': 55, '9': 66}
---------------------------------------------------------------------- 


Frequência dos dígitos no quarto dígito:
 {'0': 126, '1': 184, '2': 238, '3': 103, '4': 101, '5': 112, '6': 100, '7': 110, '8': 104, '9': 109}
---------------------------------------------------------------------- 


Frequência dos dígitos no quinto dígito:
 {'0': 97, '1': 140, '2': 74, '3': 141, '4': 23, '5': 72, '6': 32, '7': 126, '8': 362, '9': 220}
---------------------------------------------------------------------- 


Senhas de 6 Dígitos¶

In [16]:
contador = 0
print('-' * 70, '\n\n')
for pos in ['primeiro', 'segundo', 'terceiro', 'quarto', 'quinto', 'sexto']:
    digito = []
    digito_contagem = {}
    
    for i in senhas_6_digitos['senha'].values:
        digito.append(i[contador])
    
    for i in set(digito):
        digito_contagem[i] = digito.count(i)

    digito_contagem = dict(sorted(digito_contagem.items()))
    
    print(f'Frequência dos dígitos no {pos} dígito:\n', digito_contagem)
    
    fig = px.bar(x=digito_contagem.keys(), y=digito_contagem.values(), height=600, width=1200)
    fig.show()

    print('-' * 70, '\n\n')
    contador = contador + 1
---------------------------------------------------------------------- 


Frequência dos dígitos no primeiro dígito:
 {'0': 5374, '1': 8940, '2': 6798, '3': 1178, '4': 243, '5': 317, '6': 221, '7': 388, '8': 663, '9': 223}
---------------------------------------------------------------------- 


Frequência dos dígitos no segundo dígito:
 {'0': 2436, '1': 2792, '2': 2820, '3': 2331, '4': 2223, '5': 2427, '6': 2044, '7': 1999, '8': 2093, '9': 3180}
---------------------------------------------------------------------- 


Frequência dos dígitos no terceiro dígito:
 {'0': 13453, '1': 6676, '2': 673, '3': 485, '4': 281, '5': 395, '6': 438, '7': 636, '8': 697, '9': 611}
---------------------------------------------------------------------- 


Frequência dos dígitos no quarto dígito:
 {'0': 2359, '1': 3614, '2': 3597, '3': 2056, '4': 2002, '5': 2118, '6': 1910, '7': 1843, '8': 1914, '9': 2932}
---------------------------------------------------------------------- 


Frequência dos dígitos no quinto dígito:
 {'0': 4174, '1': 1578, '2': 1162, '3': 435, '4': 340, '5': 726, '6': 3087, '7': 4226, '8': 4378, '9': 4239}
---------------------------------------------------------------------- 


Frequência dos dígitos no sexto dígito:
 {'0': 2575, '1': 2380, '2': 2277, '3': 2349, '4': 2190, '5': 2459, '6': 2468, '7': 2350, '8': 2494, '9': 2803}
---------------------------------------------------------------------- 


Senhas de 7 Dígitos¶

In [17]:
contador = 0
print('-' * 70, '\n\n')
for pos in ['primeiro', 'segundo', 'terceiro', 'quarto', 'quinto', 'sexto', 'setimo']:
    digito = []
    digito_contagem = {}
    
    for i in senhas_7_digitos['senha'].values:
        digito.append(i[contador])
    
    for i in set(digito):
        digito_contagem[i] = digito.count(i)

    digito_contagem = dict(sorted(digito_contagem.items()))
    
    print(f'Frequência dos dígitos no {pos} dígito:\n', digito_contagem)
    
    fig = px.bar(x=digito_contagem.keys(), y=digito_contagem.values(), height=600, width=1200)
    fig.show()

    print('-' * 70, '\n\n')
    contador = contador + 1
---------------------------------------------------------------------- 


Frequência dos dígitos no primeiro dígito:
 {'0': 187, '1': 683, '2': 339, '3': 122, '4': 56, '5': 89, '6': 55, '7': 103, '8': 42, '9': 70}
---------------------------------------------------------------------- 


Frequência dos dígitos no segundo dígito:
 {'0': 190, '1': 357, '2': 266, '3': 145, '4': 127, '5': 191, '6': 101, '7': 102, '8': 102, '9': 165}
---------------------------------------------------------------------- 


Frequência dos dígitos no terceiro dígito:
 {'0': 564, '1': 327, '2': 185, '3': 177, '4': 65, '5': 113, '6': 63, '7': 80, '8': 86, '9': 86}
---------------------------------------------------------------------- 


Frequência dos dígitos no quarto dígito:
 {'0': 143, '1': 405, '2': 229, '3': 159, '4': 181, '5': 146, '6': 126, '7': 130, '8': 135, '9': 92}
---------------------------------------------------------------------- 


Frequência dos dígitos no quinto dígito:
 {'0': 71, '1': 750, '2': 99, '3': 121, '4': 60, '5': 160, '6': 66, '7': 85, '8': 42, '9': 292}
---------------------------------------------------------------------- 


Frequência dos dígitos no sexto dígito:
 {'0': 87, '1': 102, '2': 183, '3': 73, '4': 100, '5': 111, '6': 95, '7': 70, '8': 218, '9': 707}
---------------------------------------------------------------------- 


Frequência dos dígitos no setimo dígito:
 {'0': 145, '1': 183, '2': 94, '3': 150, '4': 67, '5': 123, '6': 100, '7': 132, '8': 438, '9': 314}
---------------------------------------------------------------------- 


Senhas de 8 Dígitos¶

In [18]:
contador = 0
print('-' * 70, '\n\n')
for pos in ['primeiro', 'segundo', 'terceiro', 'quarto', 'quinto', 'sexto', 'setimo', 'oitavo']:
    digito = []
    digito_contagem = {}
    
    for i in senhas_8_digitos['senha'].values:
        digito.append(i[contador])
    
    for i in set(digito):
        digito_contagem[i] = digito.count(i)

    digito_contagem = dict(sorted(digito_contagem.items()))
    
    print(f'Frequência dos dígitos no {pos} dígito:\n', digito_contagem)
    
    fig = px.bar(x=digito_contagem.keys(), y=digito_contagem.values(), height=600, width=1200)
    fig.show()

    print('-' * 70, '\n\n')
    contador = contador + 1
---------------------------------------------------------------------- 


Frequência dos dígitos no primeiro dígito:
 {'0': 4868, '1': 8190, '2': 5982, '3': 992, '4': 122, '5': 147, '6': 76, '7': 110, '8': 83, '9': 83}
---------------------------------------------------------------------- 


Frequência dos dígitos no segundo dígito:
 {'0': 1903, '1': 2339, '2': 2147, '3': 1941, '4': 1865, '5': 2010, '6': 1758, '7': 1753, '8': 1782, '9': 3155}
---------------------------------------------------------------------- 


Frequência dos dígitos no terceiro dígito:
 {'0': 12972, '1': 4515, '2': 359, '3': 320, '4': 208, '5': 229, '6': 194, '7': 242, '8': 1228, '9': 386}
---------------------------------------------------------------------- 


Frequência dos dígitos no quarto dígito:
 {'0': 1724, '1': 3114, '2': 3140, '3': 1845, '4': 1858, '5': 1867, '6': 1784, '7': 1800, '8': 1826, '9': 1695}
---------------------------------------------------------------------- 


Frequência dos dígitos no quinto dígito:
 {'0': 538, '1': 15047, '2': 3947, '3': 240, '4': 144, '5': 289, '6': 118, '7': 120, '8': 109, '9': 101}
---------------------------------------------------------------------- 


Frequência dos dígitos no sexto dígito:
 {'0': 3934, '1': 529, '2': 602, '3': 359, '4': 260, '5': 330, '6': 293, '7': 207, '8': 262, '9': 13877}
---------------------------------------------------------------------- 


Frequência dos dígitos no setimo dígito:
 {'0': 4190, '1': 814, '2': 629, '3': 246, '4': 230, '5': 311, '6': 2551, '7': 3867, '8': 3908, '9': 3907}
---------------------------------------------------------------------- 


Frequência dos dígitos no oitavo dígito:
 {'0': 2129, '1': 2124, '2': 2033, '3': 1979, '4': 1960, '5': 2068, '6': 2042, '7': 2040, '8': 2180, '9': 2098}
---------------------------------------------------------------------- 


In [ ]: